package com.jkdroid.maya.helper;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver;

import java.lang.ref.SoftReference;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;

/**
 * 软键盘监听器助手
 *
 * @author
 */
public class SoftKeyboardStateHelper implements
        ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);

        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<>();
    private SoftReference<View> mRootView;
//    private View activityRootView;
    private int lastSoftKeyboardHeightInPx;
    private boolean isSoftKeyboardOpened;
    private Context mContext;
    private int mVBarHeight;

    public SoftKeyboardStateHelper(Activity activity) {
        this(activity, false);
    }

    public SoftKeyboardStateHelper(Activity activity, boolean isSoftKeyboardOpened) {
        if (activity == null){
            throw new IllegalArgumentException("activity can not be null");
        }

        this.mContext = activity.getApplicationContext();
        this.mRootView = new SoftReference<>(activity.getWindow().getDecorView().getRootView());
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        if (mRootView.get() == null){
            throw new IllegalArgumentException("mRootView can not be null");
        }
        mRootView.get().getViewTreeObserver().addOnGlobalLayoutListener(this);
        int realHeightDpi = getRealHeightDpi(activity);
        int height = activity.getWindowManager().getDefaultDisplay().getHeight();
        mVBarHeight = realHeightDpi - height;

    }

    private static int getRealHeightDpi(Activity context) {
        if (context == null) {
            throw new NullPointerException("mContext can not be null");
        }
        int dpi = 0;
        Display display = context.getWindowManager().getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            dpi = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dpi;
    }

    @Override
    public void onGlobalLayout() {
        if (mRootView.get() == null){
            return;
        }
        final Rect r = new Rect();
        // r will be populated with the coordinates of your view that area still
        // visible.

        mRootView.get().getWindowVisibleDisplayFrame(r);

        int height = mRootView.get().getRootView().getHeight();
        final int heightDiff = height
                - (r.bottom - r.top) - getStatusBarHeight() - mVBarHeight;//需要减去状态栏高度，否则算出来的高度偏高
        if (!isSoftKeyboardOpened && heightDiff > mVBarHeight + 100) { // if more than 100
            // pixels, its probably
            // a keyboard...
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(heightDiff);
        } else if (isSoftKeyboardOpened && heightDiff < mVBarHeight + 100) {
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero (0)
     *
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(
            SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }

    /**
     * 获取状态栏的高度
     *
     * @return
     */
    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = mContext.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

}
